/*
 * Copyright (c) 2016 咖枯 <kaku201313@163.com | 3772304@qq.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package com.yearno.common.utils

import android.app.Activity
import android.content.Context
import android.graphics.Rect
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import android.view.Window
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent

/**
 *
 */
object KeyboardUtil {
    fun addLayoutListener(
        activity: Activity,
        lifecycle: Lifecycle,
        scroll: View,
        offset: Int = 0
    ) {
        val decorView = activity.window.decorView
        val mLsnrLayout = OnGlobalLayoutListener {
            val rect = Rect()
            decorView.getWindowVisibleDisplayFrame(rect)
            //计算出可见屏幕的高度
            val displayHight = rect.bottom - rect.top
            //获得屏幕整体的高度
            val screenHeight = decorView.height
            val mainInvisibleHeight = screenHeight - displayHight
            if (mainInvisibleHeight > screenHeight / 4) {
                val location = IntArray(2)
                scroll.getLocationInWindow(location)
                Log.i("testestest", "onGlobalLayout: location[1]" + location[1])
                val scrollBottom = scroll.bottom
                Log.i("testestest", "onGlobalLayout: scrollBottom$scrollBottom")
                val srollHeight = scrollBottom - displayHight + offset
                scroll.scrollTo(0, srollHeight)
                Log.i("testestest", "onGlobalLayout: srollHeight$srollHeight")
            } else {
                scroll.scrollTo(0, 0)
            }
        }
        lifecycle.addObserver(object : LifecycleObserver {

            @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
            fun onCreate() {
                decorView.viewTreeObserver.addOnGlobalLayoutListener(mLsnrLayout)
            }

            @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
            fun onDestroy() {
                decorView.viewTreeObserver.removeOnGlobalLayoutListener(mLsnrLayout)
            }
        })
    }

    /**
     * Hide the soft input.
     *
     * @param activity The activity.
     */
    fun hideSoftInput(activity: Activity) {
        hideSoftInput(activity, activity.window)
    }

    /**
     * Hide the soft input.
     *
     * @param window The window.
     */
    private fun hideSoftInput(context: Context, window: Window) {
        var view = window.currentFocus
        if (view == null) {
            val decorView = window.decorView
            val focusView = decorView.findViewWithTag<View>("keyboardTagView")
            if (focusView == null) {
                view = EditText(window.context)
                view.setTag("keyboardTagView")
                (decorView as ViewGroup).addView(view, 0, 0)
            } else {
                view = focusView
            }
            view.postDelayed({ //软键盘隐藏
                view.requestFocus()
                hideSoftInput(context, view)
            }, 100)
        } else {
            hideSoftInput(context, view)
        }
    }

    /**
     * Hide the soft input.
     *
     * @param view The view.
     */
    private fun hideSoftInput(context: Context, view: View) {
        val imm =
            context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, 0)
    }

    /**
     * Toggle the soft input display or not.
     */
    fun toggleSoftInput(context: Context) {
        val imm =
            context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.toggleSoftInput(0, 0)
    }

    /**
     * Fix the leaks of soft input.
     *
     * @param window The window.
     */
    fun fixSoftInputLeaks(context: Context, window: Window) {
        val imm =
            context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                ?: return
        val leakViews = arrayOf("mLastSrvView", "mCurRootView", "mServedView", "mNextServedView")
        for (leakView in leakViews) {
            try {
                val leakViewField = InputMethodManager::class.java.getDeclaredField(leakView)
                if (!leakViewField.isAccessible) {
                    leakViewField.isAccessible = true
                }
                val obj = leakViewField[imm] as? View ?: continue
                if (obj.rootView === window.decorView.rootView) {
                    leakViewField[imm] = null
                }
            } catch (ignore: Throwable) { /**/
            }
        }
    }
}